<?php
/**
 * 文件类型缓存类
 */
class FileCache extends CacheHelper
{

    /**
     * 架构函数
     * @access Public
     */
    public function __construct($options = array())
    {
        $this->options['temp'] = !empty($options['temp']) ? $options['temp'] : YucyConfig::get('data_path') . 'CacheFile';
        
        $this->expire = isset($options['expire']) ? $options['expire'] : '-1';
        
        substr($this->options['temp'], -1) != DS && $this->options['temp'] .= DS;
        
        $this->connected = is_dir($this->options['temp']);
        $this->type = 'File';
        $this->_init();
    }

    
    /**
     * 初始化检查
     * @access Private
     */
    private function _init()
    {
        $stat = stat($this->options['temp']);
        $dir_perms = $stat['mode'] & 0007777; // Get the permission bits.
        $file_perms = $dir_perms & 0000666; // Remove execute bits for files.

        // 创建项目缓存目录
        if (!is_dir($this->options['temp']) && mkdir($this->options['temp']))  chmod($this->options['temp'], $dir_perms);
        
        return ;
    }

    
    /**
     * 是否连接
     * @access public
     * @return boolen
     */
    private function isConnected()
    {
        return $this->connected;
    }

    
    /**
     * 取得变量的存储文件名
     * @access Private
     * @param String $name 缓存变量名
     * @return String
     */
    private function filename($name)
    {
        $name =	md5($name);
        $dir = substr($name, 0, 2) . DS . substr($name,2, 2) . DS;
        if(!is_dir($this->options['temp'].$dir)) $this->_mkDir($this->options['temp'].$dir);
         
        $filename =	$dir.$this->prefix.$name.'.php';
        
        return $this->options['temp'].$filename;
    }
    

    /**
     * 读取缓存
     * @access public
     * @param string $name 缓存变量名
     * @return mixed
     */
    public function get($name)
    {
        $filename = $this->filename($name);
        if (!is_file($filename)) return false;
        
        $this->Q(1);
        $content = file_get_contents($filename);
        if ($content === false) return false;
        
        $expire = (int)substr($content,8, 12);
        if($expire != -1 && time() > filemtime($filename) + $expire) {
            //缓存过期删除缓存文件
            unlink($filename);
            return false;
        }
        
        $check  =  substr($content,20, 32);
        $content   =  substr($content,52, -3);
        //校验错误
        if ($check != md5($content)) return false;

        //数据压缩
        if (function_exists('gzcompress')) $content = gzuncompress($content);
        
        $content = unserialize($content);
        return $content;
    }

    
    /**
     * 写入缓存
     * @access public
     * @param string $name 缓存变量名
     * @param mixed $value  存储数据
     * @param int $expire  有效时间 -1 为永久
     * @return boolen
     */
    public function set($name,$value,$expire='')
    {
        $this->W(1);
        if($expire === '') $expire =  $this->expire;

        $filename = $this->filename($name);
        $data = serialize($value);
        
        //数据压缩
        if(function_exists('gzcompress')) $data = gzcompress($data, 3);

        // 数据校验
        $check  =  md5($data);
        $data = "<?php\n//".sprintf('%012d', $expire).$check.$data."\n?>";
        $result = file_put_contents($filename, $data);
        
        if (!$result) return false;
        
        clearstatcache();
        return true;
    }

    /**
     * 删除缓存
     * @access public
     * @param string $name 缓存变量名
     * @return boolen
     */
    public function delete($name)
    {
        return unlink($this->filename($name));
    }

    /**
     * 清除缓存
     * @access public
     * @param string $name 缓存变量名
     * @return boolen
     */
    public function clear()
    {
        $path= $this->options['temp'];
        if ($dir = opendir($path))
        {
            while ($file = readdir($dir))
            {
                $check = is_dir($file);
                if (!$check) unlink($path . $file);
            }
            closedir($dir);
            return true;
        }
    }

	private function _mkDir($dir, $mode = 0755)
	{
	  if (is_dir($dir) || @mkdir($dir,$mode)) return true;
	  if (!$this->_mkDir(dirname($dir),$mode)) return false;
	  return @mkdir($dir,$mode);
	}
}
?>